﻿using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interactivity;
using System.Threading;
using System.Collections.Generic;
using System;
using System.Windows.Media.Imaging;
using System.Windows.Media.Animation;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Xml;

namespace MultiTouch.Behaviors.Silverlight4.TouchPPT
{
    public partial class MainPage : UserControl
    {
        private List<FrameworkElement> elementList = new List<FrameworkElement>();
        private List<MediaElement> mediaList = new List<MediaElement>();

        public MainPage()
        {
            InitializeComponent();

            DataContext = new MainPageViewModel();

            // Add images first
            int N = ((MainPageViewModel)DataContext).Count;
            for (int i = 0; i < N; i++)
            {
                Image item = new Image();
                item.Name = "image" + i.ToString();
                System.Windows.Data.Binding binding = new System.Windows.Data.Binding();
                string str = "SelectedPictures[" + i.ToString() + "]";
                binding.Path = new System.Windows.PropertyPath(str);
                item.SetBinding(Image.SourceProperty, binding);
                item.Width = 200;
                item.MouseLeftButtonDown += FrameworkElement_MouseLeftButtonDown;
                item.MouseWheel += FrameworkElement_MouseWheel;
                item.Tag = i;
                var behaviors = Interaction.GetBehaviors(item);
                var touch = new MultiTouchBehavior();
                touch.AreFingersVisible = true;
                touch.MinimumScale = 20;
                touch.MaximumScale = 200;
                behaviors.Add(touch);
                item.SetValue(Interaction.BehaviorsProperty, behaviors);
                LayoutRoot.Children.Add(item);
                elementList.Add(item);
            }

            // Then add videos and other media
            foreach (string s in ((MainPageViewModel)DataContext).MediaList)
            {
                MediaElement item = new MediaElement();
                item.Name = "media" + elementList.Count.ToString();
                item.Source = new Uri(s, UriKind.RelativeOrAbsolute);
                item.Width = 200;
                item.MouseLeftButtonDown += FrameworkElement_MouseLeftButtonDown;
                item.MouseLeftButtonDown += MediaElement_MouseLeftButtonDown;
                item.MouseWheel += FrameworkElement_MouseWheel;
                item.Tag = elementList.Count;
                item.Volume = 1;
                var behaviors = Interaction.GetBehaviors(item);
                var touch = new MultiTouchBehavior();
                touch.AreFingersVisible = true;
                touch.MinimumScale = 20;
                touch.MaximumScale = 200;
                behaviors.Add(touch);
                item.SetValue(Interaction.BehaviorsProperty, behaviors);
                LayoutRoot.Children.Add(item);
                elementList.Add(item);
                mediaList.Add(item);
            }

            // Mute videos and audios except the first one
            if (mediaList.Count > 0)
            {
                mediaList[0].IsMuted = false;
                for (int i = 1; i < mediaList.Count; i++)
                {
                    mediaList[i].IsMuted = true;
                }
            }

            Loaded += (s, a) =>
                {
                    //Initialize the items
                    ResetElements();
                };
        }

        private void image_left_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            int imageCount = ((MainPageViewModel)DataContext).Count;
            if (tag >= 0 && tag < imageCount)
            {
                imageListBox.SelectedIndex = (imageListBox.SelectedIndex - 1 + imageListBox.Items.Count) % imageListBox.Items.Count;
            }
            else
            {
                if (tag >= imageCount && tag < elementList.Count)
                {
                    int index = tag - imageCount;
                    if (mediaList[index].CanSeek)
                    {
                        mediaList[index].Position = mediaList[index].Position.Subtract(TimeSpan.FromSeconds(20));
                        mediaList[index].Play();
                    }
                }
            }
        }

        private void image_right_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            int imageCount = ((MainPageViewModel)DataContext).Count;
            if (tag >= 0 && tag < imageCount)
            {
                imageListBox.SelectedIndex = (imageListBox.SelectedIndex + 1) % imageListBox.Items.Count;
            }
            else
            {
                if (tag >= imageCount && tag < elementList.Count)
                {
                    int index = tag - imageCount;
                    if (mediaList[index].CanSeek)
                    {
                        mediaList[index].Position = mediaList[index].Position.Add(TimeSpan.FromSeconds(20));
                        mediaList[index].Play();
                    }
                }
            }
        }

        private void listBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (listBox1.SelectedIndex >= 0 && listBox1.SelectedIndex < elementList.Count)
            {
                int max = 0;
                foreach (FrameworkElement f in elementList)
                {
                    int z = Canvas.GetZIndex(f);
                    if (z > max)
                    {
                        max = z;
                    }
                }
                FrameworkElement fe = elementList[listBox1.SelectedIndex];
                Canvas.SetZIndex(fe, max + 1);
                Create_And_Run_Animation(sender, e, fe);
            }
        }

        private void image_ring_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            ResetElements();
        }

        private void ResetElements()
        {
            int r = random.Next() % 360;
            int N = elementList.Count;
            for (int i = 0; i < N; i++)
            {
                var multiTouchBehaviors =
                    System.Windows.Interactivity.Interaction.GetBehaviors(elementList[i]).OfType
                        <MultiTouchBehavior>();
                if (multiTouchBehaviors.ToList().Count > 0)
                {
                    double theta = i * 2 * Math.PI / (double)N;
                    double x = 900 + 400 * Math.Cos(theta);
                    double y = 500 + 200 * Math.Sin(theta);
                    multiTouchBehaviors.First().Move(new Point(x, y), r + i * 360 / (double)N, 150);
                }
            }
        }

        private int tag = 0;
        private void FrameworkElement_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            FrameworkElement element = (FrameworkElement)sender;
            tag = int.Parse(element.Tag.ToString());
            if (tag >= 0 && tag <= listBox1.Items.Count)
            {
                listBox1.SelectedIndex = tag;
                MainPageViewModel model = (MainPageViewModel)DataContext;
                if (tag < model.Count)
                {
                    model.SelectedPictureIndex = tag;
                    label1.Content = "Image " + model.SelectedPictureIndex.ToString();
                }
                else
                {
                    label1.Content = "Media " + (tag - model.Count).ToString();
                }
            }
            label2.Content = element.Tag;

            foreach (MediaElement m in mediaList)
            {
                if (!m.IsMuted)
                {
                    m.IsMuted = true;
                }
                if (checkBox1.IsChecked == true)
                {
                    m.Pause();
                }
            }
        }

        private void MediaElement_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            MediaElement m = ((MediaElement)sender);
            if (m.IsMuted)
            {
                m.IsMuted = false;
            }
            if (m.Position == m.NaturalDuration)
            {
                m.Stop();
            }
            m.Play();
        }

        private Random random = new Random();
        private void Create_And_Run_Animation(object sender, EventArgs e, FrameworkElement element, double increment = 240)
        {
            if (increment > 0 || element.Width > Math.Abs(increment))
            {
                // Create a duration of 2 seconds.
                Duration duration = new Duration(TimeSpan.FromSeconds(2));

                // Create two DoubleAnimations and set their properties.
                DoubleAnimation myDoubleAnimation1 = new DoubleAnimation();

                myDoubleAnimation1.Duration = duration;

                Storyboard sb = new Storyboard();
                sb.Duration = duration;

                sb.Children.Add(myDoubleAnimation1);

                Storyboard.SetTarget(myDoubleAnimation1, element);

                // Set the target property of the DoubleAnimation.
                Storyboard.SetTargetProperty(myDoubleAnimation1, new PropertyPath("(FrameworkElement.Width)"));
                myDoubleAnimation1.By = increment;

                // Make the Storyboard a resource.
                LayoutRoot.Resources.Add("unique_id_" + random.Next(), sb);

                // Begin the animation.
                sb.Begin();
            }
        }

        private void LayoutRoot_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            tabControl1.Height = e.NewSize.Height - 150;
        }

        private void FrameworkElement_MouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e)
        {
            Create_And_Run_Animation(sender, e, (FrameworkElement)sender, e.Delta * 2);
        }

    }
}
